﻿namespace MapleRock.P2PEmulator.RGR
{
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Diagnostics;
  using System.Diagnostics.CodeAnalysis;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Windows.Forms;

  using MapleRock.P2PEmulator.Core;

  public partial class ModelInputParamsPage : BasicRgrPage
  {
    public ModelInputParamsPage()
    {
      this.InitializeComponent();
    }

    public override string RgrPageName 
    {
      get { return "Параметры модели"; }
    }

    public override void OnPageEnter()
    {
      base.OnPageEnter();

      bool IsExperimentCompleted = RgrData.Instance.Experiment != null;
      if (IsExperimentCompleted)
      {
        this.Enabled = false;
      }
    }

    public override void OnPageLeave()
    {
      base.OnPageLeave();

      var wasModelParametersGathered = RgrData.Instance.InputData != null;
      if (wasModelParametersGathered)
      {
        return;
      }

      RgrData.Instance.InputData = new XmlInputData();

      this.SetInfoSpaceBounds();

      this.SetGeography();

      this.SetVariableParameter();

      this.SetMaxPeerLinksAllowedIndex();

      this.SetPeersNumberIndex();

      this.SetDimensionsIndex();

      this.SetMessageLossProbIndex();
    }

    private void SetDimensionsIndex()
    {
      Debug.Assert(
        RgrData.Instance.DimensionsIndex == -1,
        "RgrData.Instance.DimensionsIndex == -1");

      Debug.Assert(
        RgrData.Instance.VariableParameterIndex >= 0,
        "RgrData.Instance.VariableParameterIndex >= 0");

      const int DimensionsParamIndex = 2;
      if (RgrData.Instance.VariableParameterIndex == DimensionsParamIndex)
      {
        return;
      }

      if (this.radioButtonD2.Checked)       RgrData.Instance.DimensionsIndex = 0;
      else if (this.radioButtonD4.Checked)  RgrData.Instance.DimensionsIndex = 1;
      else if (this.radioButtonD6.Checked)  RgrData.Instance.DimensionsIndex = 2;
      else if (this.radioButtonD10.Checked) RgrData.Instance.DimensionsIndex = 3;
      else if (this.radioButtonD15.Checked) RgrData.Instance.DimensionsIndex = 4;

      Debug.Assert(RgrData.Instance.DimensionsIndex >= 0, "RgrData.Instance.DimensionsIndex >= 0");
      Debug.Assert(RgrData.Instance.DimensionsIndex <= 4, "RgrData.Instance.DimensionsIndex <= 4");
    }

    private void SetGeography()
    {
      RgrData.Instance.InputData.Geography = new XmlGeographyData[1];
      RgrData.Instance.InputData.Geography[0] = new XmlGeographyData();
      RgrData.Instance.InputData.Geography[0].AreaLatitude = 30;
      RgrData.Instance.InputData.Geography[0].AreaLongitude = 30;
      RgrData.Instance.InputData.Geography[0].CitiesNumber = 10;
      RgrData.Instance.InputData.Geography[0].CitySizeMax = 3;
      RgrData.Instance.InputData.Geography[0].CitySizeMin = 1;
    }

    private void SetInfoSpaceBounds()
    {
      RgrData.Instance.InputData.InfoSpaceBounds = string.Empty;

      for (var i = 0; i < RgrData.Instance.InputData.Dimensions; ++i)
      {
        RgrData.Instance.InputData.InfoSpaceBounds += "0 10 ";
      }

      RgrData.Instance.InputData.InfoSpaceBounds = RgrData.Instance.InputData.InfoSpaceBounds.TrimEnd();
    }

    private void SetMaxPeerLinksAllowedIndex()
    {
      Debug.Assert(
        RgrData.Instance.MaxPeerLinksIndex == -1, 
        "RgrData.Instance.MaxPeerLinksIndex == -1");

      Debug.Assert(
        RgrData.Instance.VariableParameterIndex >= 0, 
        "RgrData.Instance.VariableParameterIndex >= 0");

      const int MaxPeerLinksParamIndex = 3;
      if (RgrData.Instance.VariableParameterIndex == MaxPeerLinksParamIndex)
      {
        return;
      }

      if (this.radioButtonV3.Checked)    RgrData.Instance.MaxPeerLinksIndex = 0;
      if (this.radioButtonV4.Checked)    RgrData.Instance.MaxPeerLinksIndex = 1;
      if (this.radioButtonV6.Checked)    RgrData.Instance.MaxPeerLinksIndex = 2;
      if (this.radioButtonV8.Checked)    RgrData.Instance.MaxPeerLinksIndex = 3;
      if (this.radioButtonV10.Checked)   RgrData.Instance.MaxPeerLinksIndex = 4;
      if (this.radioButtonV15.Checked)   RgrData.Instance.MaxPeerLinksIndex = 5;
      if (this.radioButtonV20.Checked)   RgrData.Instance.MaxPeerLinksIndex = 6;

      Debug.Assert(RgrData.Instance.MaxPeerLinksIndex <= 6, "RgrData.Instance.MaxPeerLinksIndex <= 6");
      Debug.Assert(RgrData.Instance.MaxPeerLinksIndex >= 0, "RgrData.Instance.MaxPeerLinksIndex >= 0");
    }

    private void SetMessageLossProbIndex()
    { 
      Debug.Assert(
        RgrData.Instance.MessageLossProbIndex == -1,
        "RgrData.Instance.MessageLossProbIndex == -1");

      Debug.Assert(
        RgrData.Instance.VariableParameterIndex >= 0, 
        "RgrData.Instance.VariableParameterIndex >= 0");

      const int MessageLossProbParamIndex = 1;
      if (RgrData.Instance.VariableParameterIndex == MessageLossProbParamIndex)
      {
        return;
      }

      if (this.radioButtonPL0.Checked)    RgrData.Instance.MessageLossProbIndex = 0;
      if (this.radioButtonPL0001.Checked) RgrData.Instance.MessageLossProbIndex = 1;
      if (this.radioButtonPL0005.Checked) RgrData.Instance.MessageLossProbIndex = 2;
      if (this.radioButtonPL001.Checked)  RgrData.Instance.MessageLossProbIndex = 3;

      Debug.Assert(RgrData.Instance.MessageLossProbIndex <= 3, "RgrData.Instance.MessageLossProbIndex <= 3");
      Debug.Assert(RgrData.Instance.MessageLossProbIndex >= 0, "RgrData.Instance.MessageLossProbIndex >= 0");
    }

    private void SetPeersNumberIndex()
    {
      Debug.Assert(
        RgrData.Instance.PeersNumberIndex == -1,
        "RgrData.Instance.PeersNumberIndex == -1");

      Debug.Assert(
        RgrData.Instance.VariableParameterIndex >= 0,
        "RgrData.Instance.VariableParameterIndex >= 0");

      const int PeersNumberParamIndex = 0;
      if (RgrData.Instance.VariableParameterIndex == PeersNumberParamIndex)
      {
        return;
      }

      if (this.radioButtonPN100.Checked)    RgrData.Instance.PeersNumberIndex = 0;
      if (this.radioButtonPN1000.Checked)   RgrData.Instance.PeersNumberIndex = 1;
      if (this.radioButtonPN5000.Checked)   RgrData.Instance.PeersNumberIndex = 2;
      if (this.radioButtonPN10000.Checked)  RgrData.Instance.PeersNumberIndex = 3;
      if (this.radioButtonPN25000.Checked)  RgrData.Instance.PeersNumberIndex = 4;
      if (this.radioButtonPN50000.Checked)  RgrData.Instance.PeersNumberIndex = 5;

      Debug.Assert(RgrData.Instance.PeersNumberIndex <= 5, "RgrData.Instance.PeersNumberIndex <= 5");
      Debug.Assert(RgrData.Instance.PeersNumberIndex >= 0, "RgrData.Instance.PeersNumberIndex >= 0");
    }

    private void SetVariableParameter()
    {
      RgrData.Instance.VariableParameterIndex = this.variableSelectCb.SelectedIndex;

      switch(RgrData.Instance.VariableParameterIndex)
      {
        case 0:
          RgrData.Instance.VariableParameterAbbr = "pn";
          RgrData.Instance.VariableParameterName = "Число узлов";
          break;

        case 1:
          RgrData.Instance.VariableParameterAbbr = "pe";
          RgrData.Instance.VariableParameterName = "Вероятность потери сообщения при передаче";
          break;

        case 2:
          RgrData.Instance.VariableParameterAbbr = "d";
          RgrData.Instance.VariableParameterName = "Число измерений ИП";
          break;

        case 3:
          RgrData.Instance.VariableParameterAbbr = "v";
          RgrData.Instance.VariableParameterName = "Число связей узла";
          break;

        default:
          Debug.Assert(false, "false");
          break;
      }
    }

    private void ModelInputParamsPage_Load(object sender, EventArgs e)
    {
      this.variableSelectCb.SelectedIndex = 0;
      this.VariableSelectCb_SelectedIndexChanged(
        this.variableSelectCb.SelectedIndex, null);
    }

    private void VariableSelectCb_SelectedIndexChanged(object sender, EventArgs e)
    {
      this.groupBoxPN.Enabled = true;
      this.groupBoxPE.Enabled = true;
      this.groupBoxD.Enabled = true;
      this.groupBoxV.Enabled = true;

      var selection = Convert.ToString(this.variableSelectCb.SelectedItem);

      if (selection == "pn")
      {
        this.groupBoxPN.Enabled = false;
        return;
      }

      if (selection == "pe")
      {
        this.groupBoxPE.Enabled = false;
        return;
      }

      if (selection == "d")
      {
        this.groupBoxD.Enabled = false;
        return;
      }

      if (selection == "v")
      {
        this.groupBoxV.Enabled = false;
        return;
      }
    }

    private void groupBoxD_Enter(object sender, EventArgs e)
    {

    }
  }
}
